import dataclasses

from enum import Enum

from .metadata import *
from .property_factory import FilePropertyFactory

all_social_labels=["in_love_time","cet6","exp_province","birth_province","ranking","religious_belief","sex"]
all_psy_labels=["emotional","freshness","kindness","optimistic","responsibility"]
name2index={}


def vectorize(dataclass_obj):
    dict_obj=dataclasses.asdict(dataclass_obj)
    
    keys=list(dict_obj.keys())
    #keys.sort()
    
    result=[]
    for k in keys:
        obj=dict_obj[k]
        if isinstance(obj,float) or isinstance(obj,int):
            obj=[obj]
        result+=obj
    return result

def default_property_selector(file_info:FileInfo):
    file_property=FilePropertyFactory.create_property(file_info)
    return vectorize(file_property.ratio_property)+vectorize(file_property.vector_property)

def author_label(person_sample:PersonSample):
    person_name=person_sample.person_info.person_name
    if person_name not in name2index:
        name2index[person_name]=len(name2index)

    return [name2index[person_name]]

def default_extend_property_selector(file_info:FileInfo,obj):
    return [file_info.file_line_number,file_info.file_length]

def default_label_selector(person_extend_sample:PersonExtendSample):
    return [person_extend_sample.person_psyco_info.emotional.value]

def sex_label(person_extend_sample:PersonExtendSample):
    return [person_extend_sample.person_social_info.sex.value]

def social_label_selector_handle(attr:str,person_extend_sample:PersonExtendSample):
    social_info=person_extend_sample.person_social_info
    social_info_dict=asdict(social_info)
    
    value=social_info_dict[attr]
    if isinstance(value,Enum):
        return [value.value]
    else:
        return [value]

def psy_label_selector_handle(attr:str,person_extend_sample:PersonExtendSample):
    psy_info=person_extend_sample.person_psyco_info
    psy_info_dict=asdict(psy_info)
    
    value=psy_info_dict[attr]
    if isinstance(value,Enum):
        return [value.value]
    else:
        return [value]

def all_labels(person_extend_sample:PersonExtendSample):
    
    def enum_convert(value):
        if isinstance(value,Enum):
            return value.value
        else:
            return value
    
    social_info=person_extend_sample.person_social_info
    psy_info=person_extend_sample.person_psyco_info
    
    choose_social_labels=all_social_labels
    choose_psy_labels=all_psy_labels
    
    social_dict=asdict(social_info)
    psy_dict=asdict(psy_info)
    
    social_labels=map(enum_convert,[social_dict[e] for e in choose_social_labels])
    psy_labels=map(enum_convert,[psy_dict[e] for e in choose_psy_labels])
    
    
    return list(social_labels)+list(psy_labels)

def all_labels_extend_property_selector(file_infos:FileInfo,obj:PersonExtendSample):
    return [obj.person_sample.person_info.person_name,all_social_labels+all_psy_labels]

def author_attribution_specify_extend_property_selector(file_info:FileInfo,obj:PersonExtendSample):
    return [obj.person_sample.person_info.person_name,file_info.file_line_number,file_info.file_length]

